package cn.cuilan.service;

import cn.cuilan.entity.SysUser;
import cn.cuilan.repository.SysUserRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统用户Service
 *
 * @author zhang.yan
 */
@Service
public class SysUserService implements UserDetailsService {

    private final SysUserRepository sysUserRepository;

    private final PasswordEncoder passwordEncoder;

    public SysUserService(SysUserRepository sysUserRepository,
                          PasswordEncoder passwordEncoder) {
        this.sysUserRepository = sysUserRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser sysUserDetails = getSysUserDetails(null, username);
        if (sysUserDetails == null) {
            throw new UsernameNotFoundException("系统用户不存在");
        }
        return sysUserDetails;
    }

    /**
     * 根据系统用户id或系统用户名称查询用户详情
     *
     * @param id       系统用户id
     * @param username 系统用户名称
     * @return 返回包含角色权限等信息的用户对象
     */
    public SysUser getSysUserDetails(Long id, String username) {
        SysUser sysUser;
        if (id == null || id == 0) {
            sysUser = sysUserRepository.findByUsername(username);
        } else {
            sysUser = sysUserRepository.findById(id);
        }

        if (sysUser == null) {
            return null;
        }

        // TODO get roles from sysUser, query permission and other user details info from databases.

        return sysUser;
    }

    /**
     * 重置密码
     *
     * @param id       系统用户id
     * @param password 密码
     * @return 返回修改后的对象
     */
    public SysUser resetPassword(long id, String password) {
        SysUser sysUser = sysUserRepository.findById(id);
        Assert.notNull(sysUser, "没有该用户");
        sysUser.setPassword(passwordEncoder.encode(password));
        return sysUserRepository.save(sysUser);
    }

    /**
     * 多条件查询所有系统用户
     *
     * @param sysUser 系统用户VO对象
     * @return 返回符合条件的系统用户集合
     */
    public List<SysUser> findAllSysUser(SysUser sysUser) {
        return sysUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(sysUser.getUsername())) {
                list.add(criteriaBuilder.like(root.get("username"), "%" + sysUser.getUsername() + "%"));
            }
            if (StringUtils.isNotEmpty(sysUser.getRealName())) {
                list.add(criteriaBuilder.like(root.get("realName"), "%" + sysUser.getRealName() + "%"));
            }
            return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
        });
    }

}
